package JavaPractice;

import java.util.Scanner;

class Year {
    private int year;

    Year() {
        year = 9999;
    }

    Year(int value) {
        year = value;
    }

    int getValue() {
        return year;
    }

    void setValue(int value) {
        year = value;
    }

    boolean isLeapYear() {
        return ((year % 4)==0 && (year % 100) != 0) || !(year % 400 !=0);
    }

    boolean validate() {
        boolean is_legal = false;
        if (year >= 1820 && year <= 2020) {
            is_legal = true;
        }
        return is_legal;
    }

    void yearIncrement() {
        year++;
    }

    void yearReduction() {
        year--;
    }
}

class Month {
    private int month;
    private Year year;

    Month() {
        month = 13;
        year = new Year();
    }

    Month(int yearValue, int monthValue) {
        month = monthValue;
        year = new Year(yearValue);
    }

    int getValue() {
        return month;
    }

    void setValue(int value) {
        month = value;
    }

    Year getYear() {
        return year;
    }

    void setYear(Year value) {
        year = value;
    }

    void resetMin() {
        month = 1;
    }

    void resetMax() {
        month = 12;
    }

    boolean validate() {
        boolean legal = false;
        if (month >= 1 && month <= 12) {
            legal = true;
        }
        return legal;
    }

    void monthIncrement() {
        month++;
        if (month > 12) {
            month -= 12;
            year.yearIncrement();
        }
    }

    void monthReduction() {
        month--;
        if (month < 1) {
            this.resetMax();
            this.getYear().yearReduction();
        }
    }
}

class Day {
    private int day;
    private Month month;
    static int daysOfEachMonth[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

    Day() {
        day = 32;
        month = new Month();
    }

    Day(int yearValue, int monthValue, int dayValue) {
        day = dayValue;
        month = new Month(yearValue, monthValue);
    }

    int getValue() {
        return day;
    }

    void setValue(int value) {
        day = value;
    }

    Month getMonth() {
        return month;
    }

    void setMonth(Month value) {
        month = value;
    }

    void resetMin() {
        day = 1;
    }

    void resetMax() {
        if (month.getValue() == 2 && month.getYear().isLeapYear()) {
            day = 29;
        } else {
            day = Day.daysOfEachMonth[month.getValue()];
        }
    }

    boolean validate() {
        boolean legal = false;
        if (day >= 1 && day <= 31) {
            legal = true;
        }
        return legal;
    }

    void dayIncrement() {
        if(day == 28 && month.getYear().isLeapYear() && month.getValue() == 2)
        {
            day++;
        }
        else
        {
            day++;
            if (day > Day.daysOfEachMonth[month.getValue()]){
                this.resetMin();
                month.monthIncrement();
            }
        }
    }

    void dayReduction() {
        day--;
        if (day < 1) {
            month.monthReduction();
            this.resetMax();
        }
    }
}

class DateUtil {
    private Day today;

    DateUtil() {
        today = new Day();
    }

    DateUtil(int y, int m, int d) {
        today = new Day(y, m, d);
    }

    Day getDay() {
        return today;
    }

    void setDay(Day d) {
        today = d;
    }

    boolean checkInputValidity() {
        boolean legal = true;
        if (!today.validate()) {
            legal = false;
        }
        if (!today.getMonth().validate()) {
            legal = false;
        }
        if (!today.getMonth().getYear().validate()) {
            legal = false;
        }
        return legal;
    }

    boolean compareDates(DateUtil date) {
        // 如果输入的日期比本日期晚，返回false，否则返回true
        boolean today_is_later = true;
        if (today.getMonth().getYear().getValue() < date.getDay().getMonth().getYear().getValue()) {
            today_is_later = false;
        } else {
            if (today.getMonth().getValue() < date.getDay().getMonth().getValue()) {
                today_is_later = false;
            } else {
                if (today.getValue() < date.getDay().getValue()) {
                    today_is_later = true;
                }
            }
        }
        return today_is_later;
    }

    boolean equalTwoDates(DateUtil date) {
        boolean equal = false;
        if (today.getMonth().getYear().getValue() == date.getDay().getMonth().getYear().getValue()
                && today.getMonth().getValue() == date.getDay().getMonth().getValue()
                && today.getValue() == date.getDay().getValue()) {
            equal = true;
        }
        return equal;
    }

    String showDate() {
        return Integer.toString(today.getMonth().getYear().getValue()) + "-"
                + Integer.toString(today.getMonth().getValue()) + "-" + Integer.toString(today.getValue());
    }

    DateUtil getNextNDays(int n) {
        // 快速实现还蛮麻烦的，要考虑如果输入的天数超过400年，400年的部分只增加100个闰年周期-1天，闰年的各种情况等。正好之前写了dayIncrement等方法，便直接暴力实现。这点运算量对计算机不算什么。
        DateUtil future = new DateUtil(this.getDay().getMonth().getYear().getValue(),
                this.getDay().getMonth().getValue(), this.getDay().getValue());
        for (int i = 0; i < n; i++) {
            future.getDay().dayIncrement();
        }
        return future;
    }

    DateUtil getPreviousNDays(int n) {
        DateUtil past = new DateUtil(this.getDay().getMonth().getYear().getValue(), this.getDay().getMonth().getValue(),
                this.getDay().getValue());
        for (int i = 0; i < n; i++) {
            past.getDay().dayReduction();
        }
        return past;
    }

    int getDaysofDates(DateUtil date) {
        boolean fuck = this.compareDates(date);
        int duration = 0;
        if (fuck) {
            while (true) {
                if (date.getDay().getValue() == this.getDay().getValue()
                        && date.getDay().getMonth().getValue() == this.getDay().getMonth().getValue() && date.getDay()
                                .getMonth().getYear().getValue() == this.getDay().getMonth().getYear().getValue()) {
                    break;
                } else {
                    date = date.getNextNDays(1);
                    duration++;
                }
            }
        } else {
            while (true) {
                if (date.getDay().getValue() == this.getDay().getValue()
                        && date.getDay().getMonth().getValue() == this.getDay().getMonth().getValue() && date.getDay()
                                .getMonth().getYear().getValue() == this.getDay().getMonth().getYear().getValue()) {
                    break;
                } else {
                    date = date.getPreviousNDays(1);
                    duration++;
                }
            }
        }
        return duration;
    }
}

public class ManualDateTimeClass {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int year = 0;
        int month = 0;
        int day = 0;

        int choice = input.nextInt();

        if (choice == 1) { // test getNextNDays method
            int m = 0;
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());

            DateUtil date = new DateUtil(year, month, day);

            if (!date.checkInputValidity()) {
                System.out.println("Wrong Format");
                System.exit(0);
            }

            m = input.nextInt();

            if (m < 0) {
                System.out.println("Wrong Format");
                System.exit(0);
            }

            System.out.print(date.getDay().getMonth().getYear().getValue() + "-" + date.getDay().getMonth().getValue()
                    + "-" + date.getDay().getValue() + " next " + m + " days is:");
            System.out.println(date.getNextNDays(m).showDate());
        } else if (choice == 2) { // test getPreviousNDays method
            int n = 0;
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());

            DateUtil date = new DateUtil(year, month, day);

            if (!date.checkInputValidity()) {
                System.out.println("Wrong Format");
                System.exit(0);
            }

            n = input.nextInt();

            if (n < 0) {
                System.out.println("Wrong Format");
                System.exit(0);
            }

            System.out.print(date.getDay().getMonth().getYear().getValue() + "-" + date.getDay().getMonth().getValue()
                    + "-" + date.getDay().getValue() + " previous " + n + " days is:");
            System.out.println(date.getPreviousNDays(n).showDate());
        } else if (choice == 3) { // test getDaysofDates method
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());

            int anotherYear = Integer.parseInt(input.next());
            int anotherMonth = Integer.parseInt(input.next());
            int anotherDay = Integer.parseInt(input.next());

            DateUtil fromDate = new DateUtil(year, month, day);
            DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay);

            if (fromDate.checkInputValidity() && toDate.checkInputValidity()) {
                System.out.println("The days between " + fromDate.showDate() + " and " + toDate.showDate() + " are:"
                        + fromDate.getDaysofDates(toDate));
            } else {
                System.out.println("Wrong Format");
                System.exit(0);
            }
        } else {
            System.out.println("Wrong Format");
            System.exit(0);
        }
        input.close();
    }
}
